package com.scheduling.common.security.config;

import com.scheduling.common.security.jwt.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;
import java.util.List;

/**
 * Spring Security 配置类
 * Spring Boot 3.x + Spring Security 6.x 配置
 * 支持JWT认证和白名单URL管理
 *
 * @author 开发团队
 * @since 2025-05-29
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity()
public class SecurityConfig {
    /**
     * 白名单URL配置
     */
    private static final String[] WHITE_LIST_URLS = {
            // API文档相关 (Spring Boot 3.x + SpringDoc 2.x)
            "/v3/api-docs/**",
            "/swagger-ui/**",
            "/swagger-ui.html",
            "/swagger-resources/**",
            "/webjars/**",

            // 监控端点
            "/actuator/**",
            "/druid/**",

            // 认证相关
            "/api/user/register",
            "/api/user/login",

            // 错误页面
            "/error",

            // 静态资源
            "/favicon.ico",
            "/css/**",
            "/js/**",
            "/images/**",

            // 业务接口
            "/api/**",
            "/customer/**",
            "/product/**",
            "/order/**",
            "/work-order/**",
            "/production-task/**",
            "/machine/**",
            "/material/**",
            "/schedule/**",

    };


    /**
     * 用于 密码加密与验证
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /**
     * 自定义的 JWT 认证过滤器 Bean
     * Spring Security 会将其插入到过滤器链中，负责拦截请求并解析 JWT
     */
    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }


    /**
     * 核心安全策略配置
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // 禁用CSRF保护（因为使用JWT，不需要CSRF保护）
                .csrf(AbstractHttpConfigurer::disable)

                // 配置会话管理策略为无状态（JWT不需要session）
                .sessionManagement(session ->
                        session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))

                // 配置请求授权 - 开发测试期间允许所有请求
                .authorizeHttpRequests(authz -> authz
                                // 白名单URL无需认证
//                        .requestMatchers(WHITE_LIST_URLS).permitAll()
//                        // 其他所有请求需要认证
//                        .anyRequest().authenticated()
                                .anyRequest().permitAll()
                )

                // 配置CORS
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))

                // 配置HTTP Basic认证（用于API文档访问）
                .httpBasic(basic -> basic.realmName("production-scheduling"));

        // 开发测试期间暂时注释掉JWT认证过滤器
        // .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    /**
     * CORS配置源
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        // 允许的源
        configuration.setAllowedOriginPatterns(List.of("*"));

        // 允许的方法
        configuration.setAllowedMethods(Arrays.asList(
                "GET", "POST", "PUT", "DELETE", "OPTIONS"
        ));

        // 允许的头
        configuration.setAllowedHeaders(List.of("*"));

        // 允许凭证
        configuration.setAllowCredentials(true);

        // 预检请求的缓存时间
        configuration.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);

        return source;
    }
}